package com.demo.user.service.impl;

import com.alibaba.druid.util.StringUtils;
import com.demo.user.dao.LoginUserDaoJpa;
import com.demo.user.dto.UserDto;
import com.demo.user.entity.User;
import com.demo.user.repository.UserRepository;
import com.demo.user.service.JpaUserService;
import com.demo.user.vo.LoginVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.criteria.*;
import java.util.*;

/**
 * 用户(BlUser)表服务实现类
 *
 * @author makejava
 * @since 2023-03-24 14:32:24
 */
@Service("jpaUserService")
public class JpaUserServiceImpl implements JpaUserService {
  @Autowired
  private UserRepository userRepository;
  @Resource
  private EntityManager entityManager;

  /**
   * 分页查询
   *
   * @param userDto 筛选条件
   * @return 查询结果
   */
  @Override
  public List<User> queryByPage(UserDto userDto) {
    List<User> mdxUser = userRepository.findByNameLike(userDto.getName());
    return mdxUser;
  }

  /**
   * JPA多条件动态查询 PagingAndSortingRepository
   *
   * @param queryData
   * @return
   */
  @Override
  public List<LoginUserDaoJpa> getUserListJpa(UserDto queryData) {
    CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();

    //CriteriaQuery<?>中的泛型就是我们要接受sql返回字段的对象,可以是自定义对象
    CriteriaQuery<LoginUserDaoJpa> query = criteriaBuilder.createQuery(LoginUserDaoJpa.class);

    //相当于sql的from 表名, StudentDisciplineMappingPo就是表的po实体类
    //root就相当于from StudentDisciplineMappingPo sdm中的sdm,
    //所以root.get("id") <==> sdm.id
    Root<User> root = query.from(User.class);
//    Root<StudentDisciplineMappingPo> root = query.from(StudentDisciplineMappingPo.class);

    //参数一:disciplinePo,from表StudentDisciplineMappingPo中disciplienPo表所对应的成员变量
    //参数二:加入方法,左连接
    //返回的disciplinePoJoin就相当于join DisciplinePo d中的别名d,具体看query.multiselect
//    Join<Object, Object> disciplinePoJoin = root.join("disciplinePo", JoinType.LEFT);

    //sql语句where后面的条件一：where sdm.studentDisciplineMpUpk.disIdMp = 1
//    Predicate disId = criteriaBuilder.equal(root.get("studentDisciplineMpUpk").get("stuIdMp"), 1L);

    //条件二：sdm.studentDisciplineMpUpk.years = 2
//    Predicate years = criteriaBuilder.equal(root.get("studentDisciplineMpUpk").get("years"), "2020");

    //where语句后面两个条件中间的and：条件一 and 条件二
//    Predicate and = criteriaBuilder.and(disId, years);

    //sql语句中的select sdm.grade,d.disName;一定要和上面自定义的类(如果是自定义的话,不是就不需要)一一顺序对应
    query.multiselect(
            root.get("uid"), //相当于d.disName
            root.get("name")//相当于sdm.grade

            //求出最大值，最小值，使用criteriaBuilder调出聚合函数
            //criteriaBuilder.avg(root.get("grade")),
            //criteriaBuilder.max(root.get("grade")),
            //criteriaBuilder.min(root.get("grade"))

            //如果自定义类中的字段名和sql返回字段名不一致，使用alias取别名
            // root.get("grade").as(String.class).alias("mygrade"),
    );

    //sql语句中的where xx = xx;disId在上面定义了条件
    List<Predicate> list = new ArrayList<>();
    if (!StringUtils.isEmpty(queryData.getName())) {
      Path<String> wfNamePath = root.get("name");
      Predicate wfNameLike =
              criteriaBuilder.like(wfNamePath, "%" + queryData.getName() + "%");
      list.add(criteriaBuilder.and(wfNameLike));
    }
    Predicate[] p = new Predicate[list.size()];
    query.where(list.toArray(p));
    //排序
    query.orderBy(criteriaBuilder.desc(root.get("uid")));
//    query.where(disId);
    //利用criteriaquery返回查询结果集
    List<LoginUserDaoJpa> resultList = entityManager.createQuery(query).getResultList();
//    System.err.println(resultList);
      return resultList;
//    for (LoginUserDao loginUserDao : resultList) {
//      System.err.println(loginUserDao);
//    }
  }





  @Override
  public Map<String, Object> getUserListByPageJpa(UserDto queryData, Pageable pageable) { // 构造条件查询，根据名称查询
    Specification<User> spec = new Specification() {
      @Override
      public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder builder) {
        List<Predicate> predicates = new ArrayList<>();
        if (!StringUtils.isEmpty(queryData.getName())) {
          predicates.add(builder.equal(root.get("name"), queryData.getName()));

        }
        //未删除
        predicates.add(builder.equal(root.get("deleteStatus"), 0));
        query.where(predicates.toArray(new Predicate[predicates.size()]));
        return query.getRestriction();
      }
    };
    List<User> winesWorldnetCultureList = null;

    Page<User> pageRows = userRepository.findAll(spec, pageable);
    winesWorldnetCultureList = pageRows.getContent();
//    //  对Page数据进行封装，变成list
    List<LoginVo> resList = new ArrayList<>();
    for (User resEntity : pageRows.getContent()) {
      LoginVo resView = new LoginVo();
      BeanUtils.copyProperties(resEntity, resView);
      resList.add(resView);
    }
    System.out.println("Page数据进行封装:" + resList);
//    // 返回查询总数和对应的数据
    Map<String, Object> jsonMap = new HashMap<>();
    jsonMap.put("list", resList);
    jsonMap.put("TotalPages", pageRows.getTotalPages());
    jsonMap.put("size", pageRows.getSize());
    jsonMap.put("page", pageRows.getNumber() + 1);
    jsonMap.put("total", pageRows.getTotalElements());
return jsonMap;

    //@todo 分页打印语句
//      pageRows.getContent().forEach(System.out::println);
//      System.out.println("总页数:" + pageRows.getTotalPages());
//      System.out.println("页面记录数:" + pageRows.getSize());
//      System.out.println("当前页:" + pageRows.getNumber() + 1);
//      System.out.println("总记录数:" + pageRows.getTotalElements());
//    return winesWorldnetCultureList;

  }
}
